﻿using BLevy.Datos.Interfases;
using BLevy.Entidad;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using DapperExtensions;

namespace BLevy.Datos.Repositories
{
    public interface IServicioRepository : IRepository<Servicio>
    {
        int SolicitudServicio(ServicioSocio servicio);
        IList<ServicioSocio> FindAllSolicitudesConSocioServicio();
        IList<ServicioSocio> FindAllCondicional(string nro_servicio, string nro_cert, DateTime? desde, DateTime? hasta);
        ServicioSocio FindByIdConSocioServicio(int id);
        IList<ServicioSocio> FindServiciosByGrupoFamiliar(string grupoFamiliarL);
        int ServicioCumplimentado(ServicioSocioCompletado serviciocompletado);
        int CambiarEstadoServicioSocio(int serviciosocio_id);
    }

    public class ServicioRepository : IServicioRepository
    {
        protected readonly IDbConnection _db;

        public ServicioRepository()
        {
            try
            {
                _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString());
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<Servicio> FindAll()
        {
            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<Servicio>("SELECT * FROM SERVICIOS ORDER BY ID ASC").ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IQueryable<Servicio> Find(System.Linq.Expressions.Expression<Func<Servicio, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public Servicio FindById(int id)
        {
            string query = "SELECT * FROM SERVICIOS " +
                "WHERE ID = @id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<Servicio>(query, new { id = id }).SingleOrDefault();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int Add(Servicio newEntity)
        {
            string query = "INSERT INTO SERVICIOS (FECHAREGISTRO, SERVICIO, ACTIVO) " +
                "VALUES (@fecharegistro, @servicio, @activo)";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query, new
                    {
                        fecharegistro = DateTime.Now,
                        servicio = newEntity.servicio,
                        activo = newEntity.activo
                    });
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int Remove(int id)
        {
            string query = "UPDATE SERVICIOS SET ACTIVO = 0 " +
                "WHERE ID = @id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query, new { id = id });
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int Modify(Servicio entity)
        {
            string query = "UPDATE SERVICIOS SET SERVICIO = @servicio, ACTIVO = @activo " +
                "WHERE ID = @id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query, new
                    {
                        servicio = entity.servicio,
                        activo = entity.activo,
                        id = entity.id
                    });
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int SolicitudServicio(ServicioSocio servicio)
        {
            string query = "INSERT INTO SERVICIOSSOCIOS (SOCIO_ID, SERVICIO_ID, FECHA, BENEFICIARIO, " +
                        "DIRECCION_SALIDA, DIRECCION_DESTINO, MEDICO, OBSERVACIONES, ACTIVO) " +
                        "VALUES (@socio_id, @servicio_id, @fecha, @beneficiario, @direccion_salida, @direccion_destino, " +
                        "@medico, @observaciones, @activo);" +
                        "SELECT LAST_INSERT_ID();";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<int>(query, new
                    {
                        socio_id = servicio.socio_id,
                        servicio_id = servicio.servicio_id,
                        fecha = servicio.fecha,
                        beneficiario = servicio.beneficiario,
                        direccion_salida = servicio.direccion_salida,
                        direccion_destino = servicio.direccion_destino,
                        medico = servicio.medico,
                        observaciones = servicio.observaciones,
                        activo = servicio.activo
                    }).Single();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<ServicioSocio> FindAllSolicitudesConSocioServicio()
        {
            string query = "SELECT * FROM SERVICIOSSOCIOS " +
                "INNER JOIN SOCIOS ON SOCIOS.ID = SERVICIOSSOCIOS.SOCIO_ID " +
                "INNER JOIN SERVICIOS ON SERVICIOS.ID = SERVICIOSSOCIOS.SERVICIO_ID " +
                "ORDER BY FECHA DESC";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<ServicioSocio, Socio, Servicio, ServicioSocio>(query,
                        (serviciosocio, socio, servicio) =>
                        {
                            serviciosocio.socio = socio;
                            serviciosocio.servicio = servicio;
                            return serviciosocio;
                        }, splitOn: "id").ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<ServicioSocio> FindAllCondicional(string nro_servicio, string nro_cert, DateTime? desde, DateTime? hasta)
        {
            string query = "SELECT * FROM SERVICIOSSOCIOS " +
                "INNER JOIN SOCIOS ON SOCIOS.ID = SERVICIOSSOCIOS.SOCIO_ID " +
                "INNER JOIN SERVICIOS ON SERVICIOS.ID = SERVICIOSSOCIOS.SERVICIO_ID " +
                "WHERE ((SERVICIOS.ID = @numero_servicio) OR (@numero_servicio IS NULL)) " + 
                "AND ((SOCIOS.NUMERO_CERTIFICADO LIKE CONCAT('%', @numero_certificado, '%')) OR (@numero_certificado IS NULL)) " + 
                "AND ((SERVICIOS.FECHAREGISTRO BETWEEN @desde AND @hasta) OR ((@desde IS NULL) OR (@hasta IS NULL))) " + 
                "ORDER BY FECHA DESC";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<ServicioSocio, Socio, Servicio, ServicioSocio>(query,
                        (serviciosocio, socio, servicio) =>
                        {
                            serviciosocio.socio = socio;
                            serviciosocio.servicio = servicio;
                            return serviciosocio;
                        }, new
                        {
                            numero_servicio = nro_servicio,
                            numero_certificado = nro_cert,
                            desde = desde,
                            hasta = hasta
                        }, splitOn: "id").ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public ServicioSocio FindByIdConSocioServicio(int id)
        {
            string query = "SELECT * FROM SERVICIOSSOCIOS " +
                "INNER JOIN SOCIOS ON SOCIOS.ID = SERVICIOSSOCIOS.SOCIO_ID " +
                    "INNER JOIN SERVICIOS ON SERVICIOS.ID = SERVICIOSSOCIOS.SERVICIO_ID " +
                    "WHERE SERVICIOSSOCIOS.ID = @id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<ServicioSocio, Socio, Servicio, ServicioSocio>(query,
                        (serviciosocio, socio, servicio) =>
                        {
                            serviciosocio.socio = socio;
                            serviciosocio.servicio = servicio;
                            return serviciosocio;
                        }, new { id = id }, splitOn: "id").SingleOrDefault();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<ServicioSocio> FindServiciosByGrupoFamiliar(string grupoFamiliarL)
        {
            string query = "SELECT * FROM SERVICIOSSOCIOS " +
                "INNER JOIN SOCIOS ON SOCIOS.ID = SERVICIOSSOCIOS.SOCIO_ID " +
                    "INNER JOIN SERVICIOS ON SERVICIOS.ID = SERVICIOSSOCIOS.SERVICIO_ID " +
                    "WHERE SOCIOS.ID IN (" + grupoFamiliarL + ") " +
                    "ORDER BY SERVICIOSSOCIOS.FECHA DESC";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<ServicioSocio, Socio, Servicio, ServicioSocio>(query,
                        (serviciosocio, socio, servicio) =>
                        {
                            serviciosocio.socio = socio;
                            serviciosocio.servicio = servicio;
                            return serviciosocio;
                        }).ToList();
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }


        public int ServicioCumplimentado(ServicioSocioCompletado serviciocompletado)
        {
            string query = "INSERT INTO SERVICIOSSOCIOSCOMPLETADOS (SERVICIOSOCIO_ID, FECHA, " +
                        "OBSERVACIONES) VALUES (@serviciosocio_id, @fecha, @observaciones)";
            
            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query, new 
                    { 
                        serviciosocio_id = serviciocompletado.serviciosocio_id, 
                        fecha = serviciocompletado.fecha, 
                        observaciones = serviciocompletado.observaciones
                    });
                        
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public int CambiarEstadoServicioSocio(int serviciosocio_id)
        {
            string query = "UPDATE SERVICIOSSOCIOS SET ACTIVO = 0 " +
                "WHERE ID = @id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Execute(query, new
                    {
                        id = serviciosocio_id
                    });

                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }
}
